//封装成类
class Promise{
    //构造方法
    constructor(executor){
         //添加属性
        this.PromiseState = 'pending';
        this.PromiseResult = null;
        //声明属性,用于保存then的回调函数
        this.callbacks = [];
        //保存实例对象this的值
        const self = this;
        function resolve(data){
            //判断状态
            if(self.PromiseState !== 'pending') return;

            //1.修改promise对象状态
            self.PromiseState = 'fulfilled';
            //2.修改promise对象结果值
            self.PromiseResult = data;

            //调用成功的回调函数
            setTimeout(() => {
                self.callbacks.forEach(item => {
                    item.onResovled(data);
                });
            });
        }

        function reject(data){
            //判断状态
            if(self.PromiseState !== 'pending') return;

            //1.修改promise对象状态
            self.PromiseState = 'rejected';
            //2.修改promise对象结果值
            self.PromiseResult = data;

            //调用失败的回调函数
            setTimeout(() => {
                self.callbacks.forEach(item => {
                    item.onRejected(data);
                });
            });
        }
        
        try{
                //同步调用执行器函数
                executor(resolve, reject);
        }catch(e){
                //修改promise对象状态为rejected
                reject(e);
        }
    }

    //then方法
    then(onResovled, onRejected){
        const self = this;
        //判断回调函数参数
        if(typeof onRejected !== 'function'){
            onRejected = reason => {
                throw reason;
            }
        }
        if(typeof onResovled !== 'function'){
            onResovled = value => value;
        }
        return new Promise((resolve, reject) => {
            function callback(type){
                try{
                    //获取回调函数的执行结果
                    let result = type(self.PromiseResult);
                    //判断返回的结果是否是promise对象的实例
                    if(result instanceof Promise){
                            //如果是promise类型的对象
                            result.then(v => {
                                resolve(v);
                            },r => {
                                reject(r);
                            })
                    }else{
                        //如果result不是promise对象，则结果的对象状态设置为成功
                        resolve(result);
                    }
                }catch(e) {
                    reject(e);
                }
            }
            //调用回调函数
            //判断状态再决定调用
            if(this.PromiseState === 'fulfilled'){
                setTimeout(() => {
                    callback(onResovled);
                });
            }
            if(this.PromiseState === 'rejected'){
                setTimeout(() => {
                    callback(onRejected);
                });
            }
            //判断pending状态
            if(this.PromiseState === 'pending'){
                //保存回调函数
                this.callbacks.push({
                    onResovled: function(){
                        setTimeout(() => {
                            callback(onResovled);
                        });
                    },
                    onRejected: function(){
                        setTimeout(() => {
                            callback(onRejected);
                        });
                    }
                })
            }
        })
    }

    //catch方法
    catch(onRejected){
        return this.then(undefined, onRejected);
    }

    //resolve方法 使用static声明属于类，不属于实例对象
    static resolve(value){
        //返回Promise对象
        return new Promise((resolve, rejict) => {
            if(value instanceof Promise){
                value.then(v => {
                    resolve(v);
                }, r => {
                    rejected(r);
                })
            }else{
                //状态设置成功
                resolve(value);
            }
        })
    }

    //reject方法 
    static reject(reason){
        return new Promise((resolve, reject) => {
            reject(reason);
        })
    }

    //all方法
    static all(promises){
        //返回Promise的对象
        return new Promise((resolve, reject) => {
            let count = 0;
            let arr = [];
            //遍历
            for(let i=0; i<promises.length; i++){
                promises[i].then(v => {
                    //得知对象的状态是成功
                    //每个promise对象，都成功才能调用resolve
                    count++;
                    //将当前promise对象能成功的结果存入到数组中
                    arr[i] = v;
                    //判断
                    if(count === promises.length){
                        resolve(arr);
                    }    
                }, r => {
                    reject(r);
                })
            }
        });
    }

    //race方法
    static race(promises){
        return new Promise((resolve, reject) => {
            for(let i = 0; i < promises.length; i++){
                promises[i].then(v => {
                    //修改返回对象状态为[成功]
                    resolve(v);
                }, r => {
                    reject(r);
                })
            }
        })
    }

}